package com.github.fancyideas.controller;

import com.github.fancyideas.constance.Sex;
import com.github.fancyideas.constance.VIP;
import com.github.fancyideas.module.entity.CustomerEntity;
import com.github.fancyideas.module.entity.ShoesEntity;
import com.github.fancyideas.module.view.CustomerView;
import com.github.fancyideas.repository.CustomerRepository;
import com.github.fancyideas.repository.ShoesRepository;
import com.github.fancyideas.repository.view.CustomerViewRepository;
import com.github.fancyideas.utils.Result;
import com.github.fancyideas.utils.ResultBuilder;
import com.github.fancyideas.utils.UpdateWithoutNull;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.access.annotation.Secured;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Api(value = "客户信息", tags = {"客户信息"})
@RestController
@RequestMapping("/customer")
public class CustomerController {

    @Autowired
    private CustomerRepository customerRepository;

    @Autowired
    private CustomerViewRepository customerViewRepository;

    @Autowired
    private ShoesRepository shoesRepository;

    public void initData() {
        List<CustomerEntity> customerList = new ArrayList<>();
        int total = 100;
        while (total > 0) {
            VIP vip = total % 2 == 0 ? VIP.YES : VIP.NO;
            Sex sex = total % 2 == 0 ? Sex.MAN : Sex.WOMAN;
            CustomerEntity customer = new CustomerEntity();
            customer.setCustomerName("张" + total);
            customer.setVip(vip);
            customer.setPhone(total * 3 + "");
            customer.setSex(sex);
            customerList.add(customer);
            total--;
        }
        customerRepository.saveAll(customerList);
        // saveBeNamed 在此测试
        for (CustomerEntity customer : customerList) {
            ShoesEntity shoes = new ShoesEntity();
            shoes.setCustomerId(customer.getCustomerId());
            shoes.setPutInAddress("第弟弟");
            shoes.setPutInDate(DateTime.now().plusHours(total).toDate());
            shoesRepository.save(shoes);
        }
    }

    @ApiOperation(value = "生成测试数据", notes = "只有管理员能访问此方法，生产客户信息，每次生成100个")
    @Secured("ROLE_ADMIN")
    @GetMapping("/init")
    public String init() {
        initData();
        return "success";
    }

    @ApiOperation(value = "客户信息查询（翻页）", notes = "电话，客户名，是否VIP")
    @GetMapping("/page/{pageNo}/{pageSize}")
    public Page<CustomerView> listAll(@PathVariable int pageNo,
                                      @PathVariable int pageSize,
                                      @RequestParam(required = false) String phone,
                                      @RequestParam(required = false) String customerName,
                                      @RequestParam(required = false) VIP vip) {
        pageNo = pageNo - 1;
        Pageable pageable = PageRequest.of(pageNo, pageSize, Sort.Direction.ASC, "customerId");
        Page<CustomerView> customerViewPage = customerViewRepository.findAll(
                (Specification<CustomerView>) (root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    if (!StringUtils.isEmpty(phone)) {
                        list.add(criteriaBuilder.like(root.get("phone").as(String.class), "%" + phone + "%"));
                    }
                    if (!StringUtils.isEmpty(customerName)) {
                        list.add(criteriaBuilder.like(root.get("customerName").as(String.class), "%" + customerName + "%"));
                    }
                    if (!StringUtils.isEmpty(vip)) {
                        list.add(criteriaBuilder.equal(root.get("vip").as(VIP.class), vip));
                    }
                    Predicate[] p = new Predicate[list.size()];
                    return criteriaBuilder.and(list.toArray(p));
                }, pageable);
        return customerViewPage;
    }

    @ApiOperation(value = "查找客户信息（根据ID）", notes = "根据客户ID查找客户信息")
    @GetMapping("/{customerId}")
    public CustomerEntity getCustomer(@PathVariable Long customerId) {
        Optional<CustomerEntity> customer = customerRepository.findById(customerId);
        return customer.orElse(null);
    }

    @ApiOperation(value = "修改客户信息", notes = "根据Id修改客户信息")
    @PutMapping("/{customerId}")
    public Result update(@PathVariable Long customerId,
                         @RequestBody CustomerEntity customer) {
        CustomerEntity customerResult =
                new UpdateWithoutNull<CustomerRepository, CustomerEntity>()
                        .updateParameterWithoutNull(customerRepository, customer, customerId);
        return ResultBuilder.buildSuccess(customerResult);
    }

    @ApiOperation(value = "删除客户信息", notes = "根据ID删除客户信息")
    @DeleteMapping("/{customerId}")
    public Result delete(@PathVariable Long customerId) {
        customerRepository.deleteById(customerId);
        return ResultBuilder.buildSuccess(customerId);
    }
}
